package com.aote.expression;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import com.aote.expression.paramprocessor.MultiValueParamProcessor;
import com.aote.expression.paramprocessor.NoFitValueException;
import com.aote.expression.paramprocessor.ParamProcessor;
import com.aote.expression.paramprocessor.ParameterProcessor;
import com.browsesoft.PropertiesService;
import com.browsesoft.htmlcomponent.HTMLBasicComponent;
import com.browsesoft.user.User;

/**
 * 参数处理器工厂
 * 
 */
public class ParamProcessorFactory {

	/**
	 * 单例
	 */
	private static ParamProcessorFactory self = new ParamProcessorFactory();

	/**
	 * 保存所有默认值处理器得Map
	 */
	private static Map processors = new HashMap();

	/**
	 * 默认参数处理器标识
	 */
	private static String defaultProcessor = "";

	private ParamProcessorFactory() {
	}

	public static ParamProcessorFactory getInstance() {
		// 装载默认值处理器
		if (processors.size() == 0) {
			load();
		}
		return self;
	}

	/**
	 * 装载默认值处理器
	 * 
	 */
	private static void load() {
		try {
			Element elem = (Element) PropertiesService.getDocument()
					.getElementsByTagName("paramProcessorConfig").item(0);
			defaultProcessor = elem.getAttribute("default");
			// 取得配置
			NodeList list = elem.getChildNodes();
			for (int i = 0; i < list.getLength(); i++) {
				// 如果是元素,// 得到标记名和类名
				if (list.item(i) instanceof Element) {
					Element element = (Element) list.item(i);
					String tag = element.getTagName();
					String className = element.getAttribute("className");
					Object processor = Class.forName(className).newInstance();
					processors.put(tag, processor);
				}
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public String process(String param, Map attributes, User loginUser,
			HTMLBasicComponent component, Element config) throws NoFitValueException {
		// 创建参数对象
		Param p = new Param(param);
		// 得到处理器，送入参数处
		Object o = this.getProcessor(p.getTag());
		if (o instanceof ParamProcessor) {
			ParamProcessor dp = (ParamProcessor) o;
			return dp.process(p, attributes, loginUser, component);
		}
		ParameterProcessor dp = (ParameterProcessor)o;
		return dp.process(p, attributes, component, config);
	}

	public Collection process(String param, Map attrs,
			HTMLBasicComponent component, Element config) {
		// 创建参数对象
		Param p = new Param(param);
		// 得到处理器，送入参数处
		MultiValueParamProcessor dp = (MultiValueParamProcessor) this
				.getProcessor(p.getTag());
		return dp.process(p, attrs, component, config);
	}

	private Object getProcessor(String tag) {
		Object result = null;
		if (tag == null || tag.equals("")) {
			result = processors.get(defaultProcessor);
		} else {
			result = processors.get(tag);
		}
		if(result == null) {
			throw new RuntimeException("参数处理器不存在：" + tag);
		}
		return result;
	}
}
